#include "MD2Model.h"


MD2Model::MD2Model(void)
{
	
}


MD2Model::~MD2Model(void)
{
	delete[] m_TexCoords;
	delete[] m_Triangles;

	for(int i = 0; i < m_Header.numFrames; i++) 
	{
		delete[] m_Frames[i].verts;
	}
	delete[] m_Frames;

	delete[] m_afVertexBuffer;
	delete[] m_afTexCoordBuffer;
}

void MD2Model::LoadModel(const char* strModelName)
{

	FILE* f;
	f = fopen(strModelName, "rb");

	if(f == NULL) 
	{
		printf("Can't read %s file\n", strModelName);
		return;
	}

	fread(&m_Header, sizeof(sMD2Header), 1, f);

	if(m_Header.id != MD2_MAGIC_NUMBER || m_Header.version != 8) 
	{
		printf("This isn't MD2 file\n");
		return;
	}

	// allocate memory
	m_Frames = new sMD2Frame[m_Header.numFrames];
	for(int i = 0; i < m_Header.numFrames; i++) 
	{
		m_Frames[i].verts = new sMD2Vertex[m_Header.numVertices];
	}
	m_TexCoords = new sMD2TexCoord[m_Header.numTexCoords];
	m_Triangles = new sMD2Triangle[m_Header.numTriangles];

	m_afVertexBuffer = new float[3 * m_Header.numFrames * m_Header.numVertices];
	m_afTexCoordBuffer = new float[2 * m_Header.numTexCoords];

	// texture's name
	fseek(f, m_Header.offSkins, SEEK_SET);
	fread(m_strName, 1, 64, f);

	// read triangles
	fseek(f, m_Header.offTriangles, SEEK_SET);
	fread(&m_Triangles[0], sizeof(sMD2Triangle), m_Header.numTriangles, f);

	// read texture's coordinates
	fseek(f, m_Header.offTexCoord, SEEK_SET);
	fread(&m_TexCoords[0], sizeof(sMD2TexCoord), m_Header.numTexCoords, f); 

	// read frame
	fseek(f, m_Header.offFrames, SEEK_SET);
	for(int i = 0; i < m_Header.numFrames; i++) 
	{
		fread(&m_Frames[i], sizeof(sMD2Frame) - sizeof(sMD2Vertex*), 1, f);
		fread(m_Frames[i].verts, sizeof(sMD2Vertex), m_Header.numVertices, f);
	}

	// normalize coords
	RebuildCoords();

	fclose(f);
}

void MD2Model::Render(int frameIndex)
{
	//TODO: need to modify
	/*glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	glDrawElements(GL_TRIANGLES, 3*m_Header.numTriangles, GL_UNSIGNED_BYTE, Index); 

	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);*/
}

void MD2Model::RebuildCoords()
{
	// vertice's coords
	sMD2Frame* pFrame;
	for(int i = 0; i < m_Header.numFrames; i++)
	{
		pFrame = &m_Frames[i];
		for(int j = 0; j < m_Header.numVertices; j++) 
		{
			for(int k = 0; k < 3; k++) // iterate each axis
			{
				m_afVertexBuffer[i*m_Header.numVertices + 3*j + k] = 
					pFrame->scale[j] * pFrame->verts[j].v[k] + pFrame->translate[j];
			}
		}
	}

	// texture's coords
	for(int i = 0; i < m_Header.numTexCoords; i++) 
	{
		m_afTexCoordBuffer[2*i] = (float) m_TexCoords[i].s / m_Header.width;
		m_afTexCoordBuffer[2*i+1] = (float) m_TexCoords[i].t / m_Header.height;
	}
}

void MD2Model::AddTexture(const char* strTextureName)
{
	
}